package com.xnyzc.lhy.order.service.impl.system;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.xnyzc.lhy.common.component.redis.RedisCommon;
import com.xnyzc.lhy.common.constant.MessageConstant;
import com.xnyzc.lhy.common.constant.RedisPrefixConstant;
import com.xnyzc.lhy.common.entity.Qd;
import com.xnyzc.lhy.common.entity.Qw;
import com.xnyzc.lhy.common.entity.Rv;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.global.Configuration;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.cms.veh.EIsUse;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.DateUtil;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.common.util.TokenUtil;
import com.xnyzc.lhy.common.util.http.HttpRequestUtil;
import com.xnyzc.lhy.common.util.jt.HttpReqUtils;
import com.xnyzc.lhy.order.entity.common.gps.GpsCommon;
import com.xnyzc.lhy.order.entity.common.order.OrderCommon;
import com.xnyzc.lhy.order.entity.param.order.EndReceiptParam;
import com.xnyzc.lhy.order.entity.param.order.StartReceiptParam;
import com.xnyzc.lhy.order.entity.user.OaDUser;
import com.xnyzc.lhy.order.entity.user.OaDUserInfo;
import com.xnyzc.lhy.order.entity.vehicle.OaDDriverVehicle;
import com.xnyzc.lhy.order.entity.vehicle.OaSysVehicle;
import com.xnyzc.lhy.order.entity.vehicle.OaSysVehicleMdict;
import com.xnyzc.lhy.order.entity.work.OaDWorkRecord;
import com.xnyzc.lhy.order.mapper.area.OaSysAreaMapper;
import com.xnyzc.lhy.order.mapper.user.OaDUserInfoMapper;
import com.xnyzc.lhy.order.mapper.user.OaDUserMapper;
import com.xnyzc.lhy.order.mapper.vehicle.OaDDriverVehicleMapper;
import com.xnyzc.lhy.order.mapper.vehicle.OaSysVehicleMapper;
import com.xnyzc.lhy.order.mapper.vehicle.OaSysVehicleMdictMapper;
import com.xnyzc.lhy.order.mapper.work.OaDWorkRecordMapper;
import com.xnyzc.lhy.order.service.system.IOaSysVehicleService;
import com.xnyzc.lhy.order.service.vehicle.IOaDDriverVehicleService;
import com.xnyzc.lhy.order.service.work.IOaDWorkRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 车辆信息表 服务实现类
 * </p>
 *
 * @author bin
 * @since 2019-07-22
 */
@Service
@Slf4j
public class OaSysVehicleServiceImpl extends ServiceImpl<OaSysVehicleMapper, OaSysVehicle> implements IOaSysVehicleService {

    @Value("${global.getGreenCode}")
    private Boolean getGreenCode;

    @Autowired
    private OaDUserMapper oaDUserMapper;

    @Autowired
    private OaSysVehicleMapper oaSysVehicleMapper;
    @Autowired
    private RedisCommon redisCommon;
    @Autowired
    private OaDDriverVehicleMapper dDriverVehicleMapper;
    @Autowired
    private IOaDDriverVehicleService dDriverVehicleService;

    @Autowired
    private IOaDWorkRecordService oaDWorkRecordService;

    @Autowired
    private OaDWorkRecordMapper workRecordMapper;

    @Autowired
    private GpsCommon gpsCommon;

    @Autowired
    private OaDUserInfoMapper userInfoMapper;

    @Autowired
    private OrderCommon orderCommon;

    @Autowired
    private OaSysVehicleMdictMapper vehicleMdictMapper;

//    @Autowired
//    private OaSysAreaMapper sysAreaMapper;

    /**
     * 根据车辆id获取车辆信息
     *
     * @param vehicleId 车辆id
     * @return
     */
    @Override
    public OaSysVehicle getVehicle(Long vehicleId) {
        return oaSysVehicleMapper.selectOne(
                Wrappers.<OaSysVehicle>lambdaQuery().eq(OaSysVehicle::getVehicleId, vehicleId));
    }

    /**
     * 查询车辆列表
     * hu
     *
     * @param companyId 机构ID或公司ID
     * @param type      类型(0-空闲，1-维修中，2-使用中,-1全部)
     * @param vehNo     车牌号
     * @return
     */
    @Override
    public Rv listVehicle(Long companyId, Integer type, String vehNo) {
        Qw qw = Qw.create();
        //条件判断
        if (type != -1) {
            qw.eq("veh_status", type);
        }
        if (null != vehNo && !vehNo.equals("")) {
            qw.eq("veh_no", vehNo);
        }
        if (null != companyId && companyId > 0) {
            qw.eq("company_id", companyId);
        }
        return Rv.wrap(EErrorCode.success, oaSysVehicleMapper.selectList(qw));
    }

    /**
     * 开始接单
     *
     * @return 返回在Redis中的Key
     */
    @Override
    public Rv startReceipt(StartReceiptParam param) {
        long tokenUserId = TokenUtil.getTokenUserId();
        String tag = TokenUtil.getTag();
        // 获取司机INfo信息
        OaDUserInfo oaDUserInfo = userInfoMapper.selectOne(Qw.create().eq(OaDUserInfo.DRIVER_ID, tokenUserId));
        // 如果司机是杭州市需要判断是否有健康码
        if (getGreenCode) {
            if (String.valueOf(oaDUserInfo.getRegisterCityId()).equals("330100")) {
                // 根据身份证号判断是否有绿码
                if (!HttpReqUtils.getGreenCode(oaDUserInfo.getIdentityNumber())) {
                    throw new PangException(EErrorCode.notGreenCode);
                }
            }
        }
        //
        // 获取司机与车辆关联信息 | 查询正在使用的车辆
        OaDDriverVehicle oaDDriverVehicle = dDriverVehicleMapper.selectOne(Qw.create().eq(OaDDriverVehicle.DRIVER_ID, tokenUserId).eq(OaDDriverVehicle.IS_USE, EIsUse.yes.getValue()));
        if (CheckUtil.objIsEmpty(oaDDriverVehicle) || CheckUtil.objIsEmpty(oaDDriverVehicle.getVehicleId())) {
            throw PangException.create(EErrorCode.argCheckErr, MessageConstant.DUSER_VEHICLE_ERROR);
        }
        //获取车辆信息
        Long vehicleId = oaDDriverVehicle.getVehicleId();
        OaSysVehicle oaSysVehicle = oaSysVehicleMapper.selectById(vehicleId);
        if (CheckUtil.objIsEmpty(oaSysVehicle)) {
            throw PangException.create(EErrorCode.argCheckErr, MessageConstant.DUSER_VEHICLE_ERROR);
        }
        OaDUser oaDUser = oaDUserMapper.selectById(tokenUserId);
        if (CheckUtil.objIsNotEmpty(oaDUser)) {
            if (CheckUtil.objIsEmpty(oaDUser.getAccountStatus()) || oaDUser.getAccountStatus() != 0) {
                if (oaDUser.getAccountStatus() == 5) {
                    throw PangException.create(EErrorCode.argCheckErr, MessageConstant.ACCOUNT_SEEL_UP);
                } else {
                    throw PangException.create(EErrorCode.argCheckErr, MessageConstant.ACCOUNT_STATUS_ERROR);
                }
            }
        }
        //获取车辆类型
        try {
            OaSysVehicleMdict oaSysVehicleMdict = vehicleMdictMapper.selectOne(Qw.create().eq(OaSysVehicleMdict.CODE, oaSysVehicle.getCode()).eq(OaSysVehicleMdict.EXPAND1, 3));
            if (CheckUtil.objIsEmpty(oaSysVehicleMdict)) {
                throw PangException.create(EErrorCode.argCheckErr, MessageConstant.DUSER_VEHICLE_ERROR);
            }
        } catch (Exception e) {
            throw PangException.create(EErrorCode.argCheckErr, MessageConstant.DUSER_VEHICLE_ERROR);
        }
        //初始化数据
        Date date = new Date();
        try {
            long id = IDUtil.nextId();
            OaDWorkRecord oaDWorkRecord = new OaDWorkRecord();
            oaDWorkRecord.setCreateTime(date);
            oaDWorkRecord.setCreateUser(tokenUserId);
            oaDWorkRecord.setUpdateTime(date);
            oaDWorkRecord.setUpdateUser(tokenUserId);
            oaDWorkRecord.setStartTime(date);
            oaDWorkRecord.setStartAddress(param.getStartAddress());
            oaDWorkRecord.setStartLat(param.getStartLat());
            oaDWorkRecord.setStartLng(param.getStartLng());
            oaDWorkRecord.setRecordId(id);
            oaDWorkRecord.setDriverId(tokenUserId);
            oaDWorkRecord.setTag(tag);
            //开始接单

            oaDUserInfo.setAcceptancOrderStatus(1);
            userInfoMapper.updateById(oaDUserInfo);
            if (oaDWorkRecordService.save(oaDWorkRecord)) {
                Map<String, Object> result = new HashMap<>();
                if (DateUtil.timeIsRange(Configuration.AM_START, Configuration.AM_END)) {
                    result.put("msg", MessageConstant.VOICE_AM_START_ORDER);
                } else if (DateUtil.timeIsRange(Configuration.NOON_START, Configuration.NOON_END)) {
                    result.put("msg", MessageConstant.VOICE_NOON_START_ORDER);
                } else if (DateUtil.timeIsRange(Configuration.PM_START, Configuration.PM_END)) {
                    result.put("msg", MessageConstant.VOICE_PM_START_ORDER);
                } else if (DateUtil.timeIsRange(Configuration.NIGHT_START_FIRST, Configuration.NIGHT_END_FIRST) || DateUtil.timeIsRange(Configuration.NIGHT_START_SECOND, Configuration.NIGHT_END_SECOND)) {
                    result.put("msg", MessageConstant.VOICE_NIGHT_START_ORDER);
                } else {
                    result.put("msg", MessageConstant.VOICE_ALL_START_ORDER);
                }
                result.put("key", gpsCommon.vehKey(tokenUserId));
                return Rv.wrap(EErrorCode.success, result);
            }
            throw PangException.create(EErrorCode.addRedis);
        } catch (Exception e) {
            throw PangException.create(EErrorCode.sysError, e.getMessage());
        }
    }

    /**
     * 停止接单
     */
    @Override
    public Rv endReceipt(EndReceiptParam param) {
        long tokenUserId = TokenUtil.getTokenUserId();
        OaDUserInfo oaDUserInfo = userInfoMapper.selectOne(Qw.create().eq(OaDUserInfo.DRIVER_ID, tokenUserId));
        if (CheckUtil.objIsEmpty(oaDUserInfo)) {
            log.info("未获取用户信息!");
            throw PangException.create(EErrorCode.userFieldError);
        }
        //您有未完成的订单
        String currentOrderNo = oaDUserInfo.getCurrentOrderNo();
        if (CheckUtil.strIsNotEmpty(currentOrderNo)) {
            log.info("存在未完成的订单! orderNo: {}", currentOrderNo);
            throw PangException.create(EErrorCode.orderNotCompleted);
        }
        Date date = new Date();
        //设置司机状态为停止接单,并且未接单
        if (!orderCommon.setDriverIsOrderAndAcceptancOrderStatus(false, false, tokenUserId, "")) {
            log.info("更新司机状态失败!");
            throw PangException.create(EErrorCode.updateDriverStatusFailure);
        }
        List<OaDWorkRecord> list = workRecordMapper.selectList(Qw.create().eq(OaDWorkRecord.DRIVER_ID, TokenUtil.getTokenUserId()).isNull(OaDWorkRecord.END_TIME));
        for (OaDWorkRecord oaDWorkRecord : list) {
            if (CheckUtil.objIsEmpty(oaDWorkRecord.getEndTime())) {
                oaDWorkRecord.setEndTime(date);
                oaDWorkRecord.setUpdateTime(date);
                oaDWorkRecord.setUpdateUser(tokenUserId);
                oaDWorkRecord.setEndAddress(param.getEndAddress());
                oaDWorkRecord.setEndLat(param.getEndLat());
                oaDWorkRecord.setEndLng(param.getEndLng());
                workRecordMapper.updateById(oaDWorkRecord);
            }
        }
        //从redis中删除key
        String key = RedisPrefixConstant.GPS_VEH_KEY_PREFIX + TokenUtil.getTokenUserId();
        if (redisCommon.hashKey(key)) {
            redisCommon.remove(key);
        }
        return Rv.wrap(EErrorCode.success, Qd.create().add("msg", "停止接单"));
    }

    /**
     * 司机绑定车辆
     *
     * @param tokenUserId 司机ID
     * @param vehicleId   车辆ID
     */
    @Override
    public Rv bindVehicle(long tokenUserId, Long vehicleId) {

        /**
         * 验证车辆ID是否合法
         */
        OaSysVehicle oaSysVehicle = oaSysVehicleMapper.selectById(vehicleId);
        if (CheckUtil.objIsEmpty(oaSysVehicle)) {
            throw PangException.create(EErrorCode.argCheckErr);
        }
        //初始化参数
        Date date = new Date();
        long id = IDUtil.nextId();

        OaDDriverVehicle dDriverVehicle = new OaDDriverVehicle();
        dDriverVehicle.setCreateTime(date);
        dDriverVehicle.setCreateUser(tokenUserId);
        dDriverVehicle.setDriverId(tokenUserId);
        dDriverVehicle.setUpdateTime(date);
        dDriverVehicle.setUpdateUser(tokenUserId);
        dDriverVehicle.setLinkedId(id);
        dDriverVehicle.setVehicleId(oaSysVehicle.getVehicleId());
        //默认使用
        dDriverVehicle.setIsUse(0);
        dDriverVehicle.setDriverOnlineStatus(0);
        if (!dDriverVehicleService.save(dDriverVehicle)) {
            throw PangException.create(EErrorCode.noData);
        }
        return Rv.wrap(EErrorCode.success);
    }
}
